package com.foreverwin.mes.mq.listener;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.foreverwin.mes.common.enums.HandleEnum;
import com.foreverwin.mes.core.exception.BusinessException;
import com.foreverwin.mes.core.utils.DateUtil;
import com.foreverwin.mes.core.utils.StringUtils;
import com.foreverwin.mes.meapi.model.Operation;
import com.foreverwin.mes.meapi.model.Resrce;
import com.foreverwin.mes.meapi.model.Sfc;
import com.foreverwin.mes.meapi.service.OperationService;
import com.foreverwin.mes.meapi.service.ResrceService;
import com.foreverwin.mes.meapi.service.SfcService;
import com.sap.me.datacollection.*;
import com.sap.me.extension.Services;
import com.sap.me.frame.transitionutils.Exceptions;
import com.visiprise.globalization.DateGlobalizationServiceInterface;
import com.visiprise.globalization.GlobalizationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 设备参数收集
 *
 * @author Ervin Chen
 * @date 2020/3/19 14:33
 */
@Component
public class EquipmentDataCollectionListener {

    @Autowired
    OperationService operationService;
    @Autowired
    ResrceService resrceService;
    @Autowired
    SfcService sfcService;

    @JmsListener(destination = "eq.edc")
    public void collectParam(String message) {
        JSONObject jsonObject = JSONObject.parseObject(message);
        String reqId = jsonObject.getString("REQ_ID");
        String site = jsonObject.getString("SITE");
        String mode = jsonObject.getString("MODEL");
        String lotNo = jsonObject.getString("LOT_NO");
        String operationCode = jsonObject.getString("OPERATION");
        String resourceCode = jsonObject.getString("RESOURCE");
        JSONArray dcList = jsonObject.getJSONArray("DC_INFO");

        if (StringUtils.isBlank(site)) {
            throw BusinessException.build("mq.equipmentDataCollect.siteNotBlank", new Object[]{});
        }

        Operation operation = operationService.selectByCode(site, operationCode);
        if (operation == null) {
            throw BusinessException.build("mq.equipmentDataCollect.operationNotExist", operationCode);
        }
        String operationBo = operation.getHandle();
        //String operationBo = "OperationBO:1001,010-DRILLING,A";

        Resrce resrce = resrceService.selectByCode(site, resourceCode);
        if (resrce == null) {
            throw BusinessException.build("mq.equipmentDataCollect.resourceNotExist", resourceCode);
        }
        String resourceBo = resrce.getHandle();

        String gboRef = null;
        String dcGroup = null;
        DCGroupResponse dcGroupResponse = null;
        //设备数据收集
        if ("1".equals(mode)) {
            gboRef = resourceBo;
            dcGroupResponse = getCurrentDcGroup(site, "EDC");
        }
        //生产数据收集
        else if ("2".equals(mode)) {
            gboRef = HandleEnum.SFC.getHandle(site, lotNo);
            Sfc sfcDo = sfcService.selectById(gboRef);
            if(sfcDo == null){
                throw BusinessException.build("mq.equipmentDataCollect.lotNoNotExist", lotNo);
            }
            String itemBo = sfcDo.getItemBo();
            String item = HandleEnum.ITEM.getPart(itemBo, 1);
            try {
                dcGroupResponse = getCurrentDcGroup(site, "PDC-" + item);
            }catch (Exception e){
                dcGroupResponse = getCurrentDcGroup(site, "PDC");
            }
        }
        //模式不存在
        else {
            throw BusinessException.build("mq.equipmentDataCollect.modeNotSupport", mode);
        }

        DateGlobalizationServiceInterface dateService = (DateGlobalizationServiceInterface) GlobalizationService.getInvariantService("com.visiprise.globalization.DateGlobalizationService");
        DataCollectionServiceInterface dataCollectionServiceInterface = Services.getService("com.sap.me.datacollection", "DataCollectionService", site);
        try {
            List<CreateParametricRequest> parametricRequests = new ArrayList<>();
            for (int i = 0; i < dcList.size(); i++) {
                JSONObject dc = dcList.getJSONObject(i);
                String key = dc.getString("K");
                String value = dc.getString("V");
                Date date = DateUtil.parse(dc.getString("T"));

                DCParameterResponse dcParameterResponse = getDCParameter(site, dcGroupResponse.getDcGroupRef(), key);
                if (dcParameterResponse == null) {
                    throw BusinessException.build("mq.equipmentDataCollect.dcParameterNotExist", dcGroup, key );
                }

                ParametricDataResponse parametricDataResponse = getParametricData(site, gboRef);

                List<CreateParametricMeasure> parametricMeasures = new ArrayList<>();
                CreateParametricMeasure parametricMeasure = new CreateParametricMeasure();
                parametricMeasure.setMeasureName(key);
                parametricMeasure.setMeasureGroup(dcGroupResponse.getDcGroup());
                parametricMeasure.setDescription(dcParameterResponse.getDescription());
                parametricMeasure.setMeasureStatus(ParametricTestStatus.PASS);
                parametricMeasure.setDataType(dcParameterResponse.getDataType());
                parametricMeasure.setActual(value);
                parametricMeasure.setTestDateTime(dateService.createDateTime(date.getTime()));
                parametricMeasure.setDcParameterRef(dcParameterResponse.getRef());
                parametricMeasure.setDcGroupRevision(dcGroupResponse.getRevision());
                parametricMeasures.add(parametricMeasure);

                CreateParametricRequest request = new CreateParametricRequest();
                request.setGboRef(gboRef);
                request.setOperationRef(operationBo);
                request.setResourceRef(resourceBo);
                request.setType(DataCollectionType.MANUAL);
                request.setTestStatus(ParametricTestStatus.PASS);
                request.setTestPassed(true);
                request.setValidate(true);
                request.setParametricMeasureList(parametricMeasures);
                if (parametricDataResponse != null) {
                    request.setExistingParametricRecord(true);
                    request.setParametricRef(parametricDataResponse.getParametricRef());
                } else {
                    request.setExistingParametricRecord(false);
                }
                dataCollectionServiceInterface.createParametricData(request);
            }
        } catch (com.sap.me.frame.domain.BusinessException e) {
            throw BusinessException.build(Exceptions.convert(e).toString());
        }


    }

    /**
     * 获取数据收集参数信息
     *
     * @param site
     * @param dcGroupBo
     * @param paramName
     * @return
     */
    public DCParameterResponse getDCParameter(String site, String dcGroupBo, String paramName) {
        DCParametersResponse dcParametersResponse = null;
        DataCollectionServiceInterface dataCollectionServiceInterface = Services.getService("com.sap.me.datacollection", "DataCollectionService", site);
        try {
            DCParametersRequest dcParametersRequest = new DCParametersRequest();
            dcParametersRequest.setDcGroupRef(dcGroupBo);
            dcParametersResponse = dataCollectionServiceInterface.getDCParameters(dcParametersRequest);
            List<DCParameterResponse> dcParameterResponses = dcParametersResponse.getDcParametersList();
            for (DCParameterResponse dcParameterResponse : dcParameterResponses) {
                if (paramName.equals(dcParameterResponse.getParameterName())) {
                    return dcParameterResponse;
                }
            }
            return null;
        } catch (com.sap.me.frame.domain.BusinessException e) {
            throw BusinessException.build(Exceptions.convert(e).toString());
        }
    }

    /**
     * 获取数据收集对象信息
     *
     * @param site
     * @param gboRef
     * @return
     */
    public ParametricDataResponse getParametricData(String site, String gboRef) {
        DataCollectionServiceInterface dataCollectionServiceInterface = Services.getService("com.sap.me.datacollection", "DataCollectionService", site);
        ParametricsDataResponse parametricsDataResponse = null;
        ParametricsByReference parametricsByReference = new ParametricsByReference();
        parametricsByReference.setGboRef(gboRef);
        parametricsByReference.setErp(false);
        try {
            parametricsDataResponse = dataCollectionServiceInterface.findParametricDataByReference(parametricsByReference);
            List<ParametricDataResponse> parametricDataResponses = parametricsDataResponse.getParametricDataList();
            if (parametricsDataResponse != null && parametricsDataResponse.getParametricDataList().size() > 0) {
                return parametricDataResponses.get(0);
            } else {
                return null;
            }
        } catch (com.sap.me.frame.domain.BusinessException e) {
            throw BusinessException.build(Exceptions.convert(e).toString());
        }
    }

    /**
     * 获取数据收集组
     *
     * @param site
     * @param dcGroup
     * @return
     */
    public DCGroupResponse getCurrentDcGroup(String site, String dcGroup) {
        DataCollectionServiceInterface dataCollectionServiceInterface = Services.getService("com.sap.me.datacollection", "DataCollectionService", site);
        DCGroupRequest dcGroupRequest = new DCGroupRequest();
        dcGroupRequest.setDcGroup(dcGroup);
        DCGroupResponse dcGroupResponse;
        try {
            dcGroupResponse = dataCollectionServiceInterface.findCurrentDcGroupByName(dcGroupRequest);
        } catch (com.sap.me.frame.domain.BusinessException e) {
            throw BusinessException.build(Exceptions.convert(e).toString());
        }
        return dcGroupResponse;
    }
}
